package com.ruoyi.datastatistics.Agreement;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.springframework.stereotype.Service;

/**
 * @author kyx
 *
 */

@Service
public class SiLianV2 {
    public static void main(String[] args) {
        //byte[] data = getpacketbody(9,"0923");
        //System.out.println(CharacterParsingCommon.convertString(data));
        //byte[] data = getCurrentReading("0923001500","");
        //byte[] data = getDayReading("0923001500","","240523");
       // String temp = "6880048004688822072D00000B60040300010015109704000222100100930000000089040002221001001901000000790400022210010014000000006304000222100100630000000060040002221001009302000000530400022210010007000000005204000222100100890000000038040002221001001404000000100400022210010088000000000704000222100100750000000068180020221001FFFFFFFF020060180002221001001101000000271800022210010044010000000008000222100100420000000086070002221001009601000000800700022210010059000000007507000222100100140100000032070002221001000801000000230700022210010030010000000107000222100100230100000068180002221001FFFFFFFF02007516";
        //byte[] bit = CharacterParsingCommon.hexStringToByteArray(temp);
        //JSONObject json = GetBufferPacketForAll(bit);
        byte[] bit = {(byte) 0x80,0x04};

        System.out.println(getpacketLength(bit));
        //System.out.println(CharacterParsingCommon.convertString(data));
    }
    // 00H 确认∕否认
    //01H 复位
    //02H 链路接口检测
    //03H 设置参数
    //04H 控制命令
    //05H~09H 备用
    //0AH 查询参数
    //0BH 请求 1 类数据（实时数据）
    // 0CH 请求 2 类数据（历史数据）
    // 0DH 数据转发（如通过管理中心对表进行直接通讯）
    // 0EH~FFH 备用
    public static byte[] AFN = { 0x00, 0x01,0x02,0x03,0x04,0x0a,0x0b,0x0c,0x0d };
    public static byte[][] Fn = {
            {},
            {},
            {},
            {},
            {},
            {  0x01,0x02,0x03,0x04,0x06,0x07,0x08 },
            {0x01,0x02,0x4,0x6},
            {0x01,0x02}
    };

    /**
     * 解析日冻结数据
     * @param bit
     * @return
     */
    public static JSONObject GetBufferPacketForAll(byte[] bit)
    {

        JSONObject jo = new JSONObject();
        byte[] type = { 0x04 };
        boolean flag = getCsForAllType(bit, 8, type);
        if (flag)
        {
            try
            {
                jo = getDSDateinfoFromByte(bit,0);
                //jo = getDSDateinfoFromByte(bit);
            }
            catch (Exception e)
            {
                return null;
            }
            return jo;
        }
        else
        {
            return null;
        }

    }

    /**
     *
     * @param bit
     * @param type 0：当前数据、1：日冻结数据，2：月冻结数据
     * @return
     */
    public static JSONObject getDSDateinfoFromByte(byte[] bit,int type)
    {
        JSONObject jo = new JSONObject();
        try
        {
            if (bit.length > 8)
            {
                jo.put("type", 5);
                jo.put("type_msg", "集中器四联");//终端类型
                byte[] temp = new byte[5];
                System.arraycopy(bit, 7, temp, 0, temp.length);
                jo.put("add", getAddressFieldPacket(temp));//终端类型
                Integer index_num = 21;//163301112110 01 00000000 //水表状态00 00
                JSONArray json_temp = new JSONArray();
                temp = new byte[2];
                System.arraycopy(bit, 15, temp, 0, temp.length);
                jo.put("total", Integer.parseInt(CharacterParsingCommon.get16tobcd(temp,true)));
                System.arraycopy(bit, 17, temp, 0, temp.length);
                jo.put("xh", Integer.parseInt(CharacterParsingCommon.get16tobcd(temp,true)));
                try{
                    while (index_num < bit.length-2)
                    {
                        JSONObject item = new JSONObject();
                        try{

                            temp = new byte[6];
                            System.arraycopy(bit, index_num, temp, 0, temp.length);
                            String meterAddress = CharacterParsingCommon.get16tobcd(temp,true);
                            item.put("add", meterAddress);
                            //流量 只取一个因子,单位固定为立方米
                            temp = new byte[4];
                            System.arraycopy(bit, index_num + 8, temp, 0, temp.length);//根据解析后数据 猜8

                            item.put("totalFlow", Integer.parseInt(CharacterParsingCommon.get16tobcd(temp,true)));
                            //阀控
                            temp = new byte[1];
                            System.arraycopy(bit, index_num + 11, temp, 0, temp.length);
                            item.put("valveStatus", getValveStatus(temp[0]));

                            //电池
                            temp = new byte[1];
                            System.arraycopy(bit, index_num + 12, temp, 0, temp.length);
                            item.put("voltage", getPressureVFromByte(temp));
                        }catch (Exception e){
                            System.out.println(e.getMessage());

                        }

                        index_num = index_num + 13 ;
                        json_temp.add(item);
                    }
                }catch (Exception e){
                    System.out.println(e.getMessage());
                }

                jo.put("info", json_temp);

            }

        }
        catch (Exception e)
        {

        }
        return jo;
    }
    //解析压力域
    public static String getPressureVFromByte(byte[] bit)
    {
        String str = "";
        double d = 100;
        d = Double.parseDouble(Integer.toHexString(bit[0]& 0xFF)+200)/d;
        return d + "";
    }
    /**
     * 解析 阀控 状态
     * @param bit
     * @return
     */
    public static String getValveStatus(byte bit){
        String binaryString = String.format("%8s", Integer.toBinaryString(bit & 0xFF)).replace(' ', '0');

        String flag = "3";
        if(binaryString.substring(0,2).equals("00")){
            flag = "1";//开阀
        }else {
            flag = "0";//关阀
        }
        return flag;
    }
    /**
     * 验证
     * @param bit
     * @param index
     * @param type
     * @return
     */
    public static boolean getCsForAllType(byte[] bit, int index, byte[] type)
    {
        boolean flag = true;
        if (bit != null & bit.length > 0)
        {

            if (flag)
            {
                if (bit.length <= 0)
                {
                    flag = false;
                }
                else if (bit[0] != (byte)0x68)
                {
                    flag = false;
                }
                else if (bit[12] != (byte)0x0B)
                {
                    flag = false;
                }
                else if (bit[14] != (byte)0x04)
                {
                    flag = false;
                }
                else if (bit[(bit.length - 1)] !=  (byte)0x16)
                {
                    flag = false;
                }
                else
                {
                    byte[] temp1 = new byte[bit.length - 8];
                    System.arraycopy(bit, 6, temp1, 0, temp1.length);
                    byte temp = CharacterParsingCommon.getTotalForByte(temp1);
                    if (temp != bit[(bit.length - 2)])
                    {
                        flag = false;
                    }
                }
            }

        }

        return flag;
    }
    /**
     * 实时数据
     * @param concentratorAddress
     * @param meterAddress
     * @return
     */
    public static byte[] getCurrentReading(String concentratorAddress,String meterAddress){

        byte[] bit = new byte[8];
        bit[0] = 0x10;
        byte[] temp = new byte[6];
        temp = new byte[]{(byte)0xFF,(byte)0xFF,0x00,0x00,(byte)0xFF,(byte)0xFF};
        temp = "".equals(meterAddress)? temp : CharacterParsingCommon.get16tobcd(meterAddress,false);
        System.arraycopy(temp, 0, bit, 1, temp.length);
        bit[7] = 0x45;
        return getpacketbody(concentratorAddress,6,2,bit);
    }

    /**
     * 日冻结数据
     * @param concentratorAddress
     * @param meterAddress
     * day 240523
     * @return
     */
    public static byte[] getDayReading(String concentratorAddress,String meterAddress,String day){

        byte[] bit = new byte[11];
        byte[] temp = new byte[3];
        temp = CharacterParsingCommon.get16tobcd(day,false);
        System.arraycopy(temp, 0, bit, 0, temp.length);
        bit[3] = 0x10;
        temp = new byte[6];
        temp = new byte[]{(byte)0xFF,(byte)0xFF,0x00,0x00,(byte)0xFF,(byte)0xFF};
        temp = "".equals(meterAddress)? temp : CharacterParsingCommon.get16tobcd(meterAddress,false);
        System.arraycopy(temp, 0, bit, 4, temp.length);
        bit[10] = 0x45;
        return getpacketbody(concentratorAddress,7,0,bit);
    }
    /**
     * 获取完整数据包
     * @return
     */
    public static byte[] getpacketbody(int num,String address){
        byte[] bit = new byte[8+num];
        bit[0] = 0x68;
        byte[] temp = new byte[2];//长度
        temp = getpacketLength(num);
        System.arraycopy(temp, 0, bit, 1, 2);
        System.arraycopy(temp, 0, bit, 3, 2);
        bit[5] = 0x68;
        bit[6] = getControlPacket(1);
        temp = new byte[5];//地址域
        temp = getAddressFieldPacket(address);
        System.arraycopy(temp, 0, bit, 7, 5);
        //AFN
        bit[12] = AFN[5];
        //seq
        bit[13] = getSEQPacket(1,1,0);
        //fn
        bit[14] = Fn[5][2];
        //验证和
        temp = new byte[num];//地址域
        System.arraycopy(bit, 6, temp, 0, num);
        bit[bit.length-2] = CharacterParsingCommon.getTotalForByte(temp);
        bit[bit.length-1] = 0x16;
        return bit;
    }

    /**
     *
     * @param address 集中器地址
     * @param afntype
     * @param fntype
     * @param body 其他
     * @return
     */
    public static byte[] getpacketbody(String address,int afntype,int fntype,byte[] body){
        int num = 9 + body.length;
        byte[] bit = new byte[8+num];
        bit[0] = 0x68;
        byte[] temp = new byte[2];//长度
        temp = getpacketLength(num);
        System.arraycopy(temp, 0, bit, 1, 2);
        System.arraycopy(temp, 0, bit, 3, 2);
        bit[5] = 0x68;
        bit[6] = getControlPacket(1);
        temp = new byte[5];//地址域
        temp = getAddressFieldPacket(address);
        System.arraycopy(temp, 0, bit, 7, 5);
        //AFN
        bit[12] = AFN[afntype];
        //seq
        bit[13] = getSEQPacket(1,1,0);
        //fn
        bit[14] = Fn[afntype][fntype];
        if(body != null){
            System.arraycopy(body, 0, bit, 15, body.length);
        }
        //验证和
        temp = new byte[num];//地址域
        System.arraycopy(bit, 6, temp, 0, num);
        bit[bit.length-2] = CharacterParsingCommon.getTotalForByte(temp);
        bit[bit.length-1] = 0x16;
        return bit;
    }

    /**
     * 字节总数---控制域、地址域、链路用户数据（应
     * 用层）的字节总数
     * @return
     */
    public static byte[] getpacketLength(int num){
        String binaryString = Integer.toBinaryString(num);
        String binaryString0 = binaryString.length()>8 ? binaryString.substring(binaryString.length()-7,binaryString.length()-1) + "11" : binaryString+ "11";
        String binaryString1 = binaryString.length()>8 ? binaryString.substring(0,binaryString.length()-8)  : "0";
        byte[] bit = new byte[2];
        bit[0] = (byte)Integer.parseInt(binaryString0, 2);
        bit[1] = (byte)Integer.parseInt(binaryString1, 2);
        return bit;
    }
    /**
     * 字节总数---控制域、地址域、链路用户数据（应
     * 用层）的字节总数
     * @return
     */
    public static int getpacketLength(byte[] bit){
        String hexString = "";
        for (byte b : bit) {
            hexString = String.format("%02X", b) + hexString;
        }
        int intValue = Integer.parseInt(hexString, 16);
        String binaryString = Integer.toBinaryString(intValue);
        binaryString = binaryString.substring(0,binaryString.length()-2);

        intValue = Integer.parseInt(binaryString, 2);

        return intValue;
    }

    /**
     * 控制码
     * @param dir
     * @param prm
     * @param functioncode
     * @return
     */
    public static byte[] getControlPacket(int dir, int prm, int functioncode){


        return null;
    }
    public static byte getControlPacket(int type){

        return type==1? (byte)0x4b : 0x4a;
    }
    /**
     * 地址域
     * @param address 行政码+设备地址，例如行政0923设备地址0015补充零
     * @return 2309150000 bcd码，前高后低
     */
    public static byte[] getAddressFieldPacket(String address){
        int length = address.length()/2;
        byte[] bit = new byte[5];
        byte[] temp = new byte[2];
        temp = CharacterParsingCommon.get16tobcd(address.substring(0,4),false);
        System.arraycopy(temp, 0, bit, 0, 2);
        temp = new byte[2];
        temp = new byte[]{(byte)0xFF, (byte)0xFF, 0x00};
        temp = address.length()<5? temp : CharacterParsingCommon.get16tobcd(address.substring(4,8),false);
        System.arraycopy(temp, 0, bit, 2, temp.length);
        bit[4] = 0x00;
        return bit;
    }
    /**
     * 地址域
     * @param bit 行政码+设备地址，例如行政0923设备地址0015补充零
     * @return 2309150000 bcd码，前高后低
     */
    public static String getAddressFieldPacket(byte[] bit){
        String address = "";
        byte[] temp = new byte[2];
        System.arraycopy(bit, 0, temp, 0, 2);
        address = CharacterParsingCommon.get16tobcd(temp,true);

        temp = new byte[2];
        System.arraycopy(bit, 2, temp, 0, 2);
        address = address + CharacterParsingCommon.get16tobcd(temp,true);
        address = address +"00";
        return address;
    }

    /**
     * SEQ
     * @param fir 报文的第一帧
     * @param fin 报文的最后一帧
     * @param con 请求确认标志位 CON
     * @return
     */
    public static byte getSEQPacket(int fir,int fin,int con){
       String str = String.valueOf(fir)  + String.valueOf(fin) + String.valueOf(con)+ "0000";
        return (byte)Integer.parseInt(str, 2);
    }

}
